package com.fast.generator;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.dialect.Props;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.fast.generator.custom.AutoGeneratorCustom;
import com.fast.generator.custom.GlobalConfigCustom;

import java.util.*;

/**
 * MybatisPlus代码生成工具
 *
 * @author solo
 * @date 2019-06-27 10:04
 **/
public class MPGeneratorTool {


    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入" + tip + "：");
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    /**
     * 根据配置文件执行生成
     *
     * @param propertiesFilePath properties配置文件绝对路径
     */
    public void generator(String propertiesFilePath) {
        Props props = new Props(FileUtil.touch(propertiesFilePath), CharsetUtil.UTF_8);

        AutoGeneratorCustom generator = new AutoGeneratorCustom();
        //AutoGenerator generator = new AutoGenerator();
        // 全局配置
        GlobalConfigCustom config = new GlobalConfigCustom();
        config.setKotlin(false);  //是否生成 kotlin 代码
        config.setOpen(false);
        config.setAuthor(props.getStr("global.author"));
        config.setOutputDir(props.getStr("global.outputDir"));
        config.setOutputControllerDir(props.getStr("global.outputControllerDir"));
        config.setUnityUrl(props.getStr("global.unityUrl"));
        config.setControllerModelName(props.getStr("package.controllerModuleName"));




        // 指定生成的主键的ID类型
        config.setIdType(IdType.NONE);

        // 是否覆盖已有文件
        config.setFileOverride(true);
        // 不需要ActiveRecord特性的请改为false
        config.setActiveRecord(false);
        // XML 二级缓存
        config.setEnableCache(false);
        // XML ResultMap
        config.setBaseResultMap(true);
        // XML columList
        config.setBaseColumnList(false);
        // 只使用 java.util.date 代替
        config.setDateType(DateType.TIME_PACK);
        // 开启 swagger2 模式
        //gc.setSwagger2(true);
        generator.setGlobalConfigCustom(config);

        // 数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);
//        dsc.setTypeConvert(new MySqlTypeConvert() {
//            // 自定义数据库表字段类型转换【可选】
//            @Override
//            public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
//                // 注意！！processTypeConvert 存在默认类型转换，如果不是你要的效果请自定义返回、非如下直接返回。
//                return super.processTypeConvert(globalConfig, fieldType);
//            }
//        });
        dataSourceConfig.setDriverName(props.getStr("datasource.driverName"));
        dataSourceConfig.setUrl(props.getStr("datasource.url"));
        dataSourceConfig.setUsername(props.getStr("datasource.username"));
        dataSourceConfig.setPassword(props.getStr("datasource.password"));
        generator.setDataSource(dataSourceConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();

        TableFill tableFill = new TableFill("create_time", FieldFill.INSERT);
        TableFill tableFill2= new TableFill("update_time", FieldFill.INSERT_UPDATE);
        List<TableFill> arr = new ArrayList<>();
        arr.add(tableFill);
        arr.add(tableFill2);
        strategy.setTableFillList(arr);


        // 是否为lombok模型（默认 false）
        strategy.setEntityLombokModel(props.getBool("strategy.entityLombokModel", false));
        // 【实体】是否生成字段常量（默认 false）
        //public static final String ID = "auto_id";
        strategy.setEntityColumnConstant(false);
        // 【实体】是否为构建者模型（默认 false）
        // public User setName(String name) {this.name = name; return this;}
        // strategy.setEntityBuliderModel(true);
        // 生成 <code>@RestController</code> 控制器 （默认 false）
        strategy.setRestControllerStyle(true);
        // 驼峰转连字符 <code>@RequestMapping("/managerUserActionHistory")</code> -> <code>@RequestMapping("/manager-user-action-history")</code>
        strategy.setControllerMappingHyphenStyle(false);


        // 此处可以修改为您的表前缀
        strategy.setTablePrefix(props.getStr("strategy.tablePrefix"));
        // 表名生成策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        // 需要生成的表
        //strategy.setInclude(StrUtil.split(scanner("表名"), ","));
        strategy.setInclude(StrUtil.split(props.getStr("strategy.include"), ","));
        // 排除生成的表
        strategy.setExclude(StrUtil.split(props.getStr("strategy.exclude"), ","));
        // 自定义实体父类
        strategy.setSuperEntityClass(props.getStr("strategy.superEntityClass"));
        // 自定义实体，公共字段
        strategy.setSuperEntityColumns(StrUtil.split(props.getStr("strategy.superEntityColumns"), ","));


        // 自定义 mapper 父类
        strategy.setSuperMapperClass(props.getStr("strategy.superMapperClass"));
        // 自定义 service 父类
        strategy.setSuperServiceClass(props.getStr("strategy.superServiceClass"));
        // 自定义 service 实现类父类
        strategy.setSuperServiceImplClass(props.getStr("strategy.superServiceimplClass"));
        // 自定义 web 父类
        strategy.setSuperControllerClass(props.getStr("strategy.superControllerClass"));

        generator.setStrategy(strategy);

        // 包配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent(props.getStr("package.parent"));
        packageConfig.setModuleName(props.getStr("package.moduleName"));

        packageConfig.setController(props.getStr("package.controller"));

        generator.setPackageInfo(packageConfig);

        // 注入自定义配置，可以在 VM 中使用 cfg.abc 【可无】
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>(1);
                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
                this.setMap(map);
            }
        };
        generator.setCfg(cfg);

        // 根据构建的项目类型来选择模板
        TemplateConfig templateConfig = new TemplateConfig();
        //templateConfig.setController("");
        //templateConfig.setController("templates/controller.java.vm");

        generator.setTemplate(templateConfig);


        // 执行生成
        generator.execute();
    }
}
